package org.os.framework.crypto.engine;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAKeyGenParameterSpec;
import java.security.spec.X509EncodedKeySpec;

import org.os.framework.crypto.model.Generator;
import org.os.framework.crypto.model.Keypair;

import cn.hutool.core.codec.Base64;
import lombok.SneakyThrows;

/**
 * @author
 */
public class RsaGenerator implements Generator {

    private final RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(1024, RSAKeyGenParameterSpec.F4);
    private final String algorithm = "RSA";

    @SneakyThrows
    @Override
    public Keypair generate() {
        KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithm);
        generator.initialize(spec, new SecureRandom());
        KeyPair kp = generator.generateKeyPair();
        KeyFactory factory = KeyFactory.getInstance(algorithm);
        X509EncodedKeySpec x509 = new X509EncodedKeySpec(kp.getPublic().getEncoded());
        RSAPublicKey rsaPublicKey = (RSAPublicKey) factory.generatePublic(x509);
        PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(kp.getPrivate().getEncoded());
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) factory.generatePrivate(pkcs8);
        String publicKey = Base64.encode(rsaPublicKey.getEncoded());
        String privateKey = Base64.encode(rsaPrivateKey.getEncoded());
        return Keypair.builder()
                .publicKey(publicKey)
                .privateKey(privateKey)
                .build();
    }

}
